﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebCalendar.Mailers;
using WebCalendar.Models;
using WebCalendar.Models.Authorization;
using WebCalendar.Models.DTOs;

namespace WebCalendar.Controllers
{
    public class AppointmentController : Controller
    {
        //
        // GET: /Appointment/5
        private WebCalendarContext db = new WebCalendarContext();
        private IUserMailer _userMailer = new UserMailer();
        public IUserMailer UserMailer
        {
            get { return _userMailer; }
            set { _userMailer = value; }
        }

        public ActionResult Index(int id, int? year, int? month)
        {
            var date = DateTime.Now;
            if (year.HasValue && month.HasValue) date = new DateTime((int)year, (int)month, 1);
            return View(new CalendarIndexDTO { CalendarID = id, Month = date.Month, Year = date.Year });
        }


        public ActionResult Get(int id, int? year, int? month)
        {
            if (!month.HasValue) month = DateTime.Now.Month;
            if (!year.HasValue) year = DateTime.Now.Year;
            var user = WebCalendarUser.GetUserProfile(db);
            var calendar = db.Calendars.Include("CalendarRoles").FirstOrDefault(m => m.ID == id);
            var isOwner = calendar.CalendarRoles.OfType<OwnerRole>().FirstOrDefault().User == user;
            var apps = db.AppointmentRequests.Where(m => m.Calendar.ID == id 
                && m.RequestedStartDate != null 
                && !m.AcceptDate.HasValue
                && !m.RefuseDate.HasValue
                && m.RequestedStartDate.Year == year 
                && m.RequestedStartDate.Month == month
                ).OrderBy(m => m.RequestedStartDate).ToList();
            if (isOwner)
            {
                   return Json( new
                    {
                        Apps = apps.Select(m => new AppointmentRequestData
                        {
                           Title = m.Title,
                           Description = m.Description,
                           StartDate = m.RequestedStartDate,
                           EndDate = m.RequestedEndDate,
                           Email = m.RequestorEmail,
                           Phone = m.RequestorPhoneNumber,
                           Name = m.RequestorName,
                           IsAllDay = m.IsAllDay,
                           URLCode = m.URLCode.ToString()
                        })
                    }, JsonRequestBehavior.AllowGet);
            }
            else if (calendar.IsPublic && !isOwner)
            {
                return Json(new
                {
                    Apps = apps.Select(m => new AppointmentRequestData
                    {
                        StartDate = m.RequestedStartDate,
                        EndDate = m.RequestedEndDate,
                        IsAllDay = m.IsAllDay
                    })
                }, JsonRequestBehavior.AllowGet);

            }
            else
            {
                return Json(new
                {
                    Apps = new List<AppointmentRequestData>()
                }, JsonRequestBehavior.AllowGet);
            }
        }
        [HttpPost]
        public ActionResult Add(int id, AppointmentRequestData appointment)
        {

            var calendar = db.Calendars.Find(id);
            if (String.IsNullOrEmpty(appointment.StartDateString))
            {
                appointment.IsAllDay = true;
            }
            else
            {
                appointment.StartDate = DateTime.Parse(appointment.StartDateString);
                if (!String.IsNullOrEmpty(appointment.EndDateString))
                {
                    appointment.EndDate = DateTime.Parse(appointment.EndDateString);
                }
                appointment.IsAllDay = false;
            }

            var user = WebCalendarUser.GetUserProfile(db);
            var dbAppointment = new AppointmentRequest
            {
                URLCode = Guid.NewGuid(),
                Calendar = calendar,
                Title = appointment.Title,
                Description = appointment.Description,
                RequestedStartDate = appointment.StartDate,
                RequestedEndDate = appointment.EndDate,
                IsAllDay = appointment.IsAllDay,
                RequestDate = DateTime.Now,
                RequestorName = appointment.Name,
                RequestorPhoneNumber = appointment.Phone,
                RequestorEmail = appointment.Email,
                RequestorUserProfile = user
            };

            db.AppointmentRequests.Add(dbAppointment);
            if (db.SaveChanges() > 0)
            {
                var r = db.CalendarRoles.Include("User");
                var rolesE = r.Where(m => m.Calendar.ID == calendar.ID);
                var roles = rolesE.ToList();
                var ownerRoles = roles.OfType<OwnerRole>();
                var ownerRole = ownerRoles.FirstOrDefault();
                if (ownerRole != null)
                {
                    var owner = ownerRole.User;
                    UserMailer.NewAppointmentRequest(new NewAppointmentRequestData { Addressee = owner.Email, AdresseeUser = owner, Subject = "New appointment request", ViewName = "NewAppointmentRequestMail", Appointment = dbAppointment }).Send();
                    return Json(new { success = true, ID = dbAppointment.ID, URLCode = dbAppointment.URLCode.ToString() });
                }
            }


            return Json(new { success = false, message="nothing has changed in the database." });
        }
        /// <summary>
        /// Elfogadja az appointmentet
        /// </summary>
        /// <param name="id">AppointmentRequest.URLCode</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Accept(string id)
        {
            Guid guid;
            Guid.TryParse(id, out guid);
            var appRequest = db.AppointmentRequests.Include("Calendar").FirstOrDefault(m=> m.URLCode == guid);
            appRequest.AcceptDate = DateTime.Now;
            var user = WebCalendarUser.GetUserProfile(db);

            var dbEnty = new Entry { Title = appRequest.Title, Description = appRequest.Description, StartDate = appRequest.RequestedStartDate, EndDate = appRequest.RequestedEndDate, IsAllDay = appRequest.IsAllDay };
            db.Entries.Add(dbEnty);
            var category = user.Categories.FirstOrDefault();
            var personalEntry = new PersonalEntry { EntryBase = dbEnty, Category = category };
            db.PersonalEntries.Add(personalEntry);
            var entryFilter = new EntryFilter { Entry = personalEntry, Calendar = appRequest.Calendar, Visible = true };
            db.EntryFilters.Add(entryFilter);
            if (db.SaveChanges() > 0)
            {
                var ownerRole = db.CalendarRoles.Include("User").Where(m => m.Calendar.ID == appRequest.Calendar.ID).ToList().OfType<OwnerRole>().FirstOrDefault();
                var owner = ownerRole.User;
                try
                {
                    UserMailer.AcceptedAppointmentRequest(new AcceptedAppointmentRequestData { Addressee = appRequest.RequestorEmail, CalendarOwnerName = owner.Name, Subject = "Accepted appointment request", ViewName = "AcceptedAppointmentRequestMail", Appointment = appRequest }).Send();
                }catch(Exception e){
                }
                return Json(new
                {
                    success = true,
                    entry = new EntryData
                    {
                        Category = new Category { Color = category.Color, Name = category.Name, ID = category.ID },
                        CategoryID = category.ID,
                        Description = dbEnty.Description,
                        Title = dbEnty.Title,
                        StartDate = dbEnty.StartDate,
                        EndDate = dbEnty.EndDate,
                        IsAllDay = dbEnty.IsAllDay,
                        ID = personalEntry.ID
                    }
                });
            }

            return Json(new { success = false, message = "something went wrong" });
        }


        /// <summary>
        /// Elutasítja az appointmentet
        /// </summary>
        /// <param name="id">AppointmentRequest.URLCode</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Refuse(string id)
        {
            Guid guid;
            Guid.TryParse(id, out guid);
            var appRequest = db.AppointmentRequests.Include("Calendar").FirstOrDefault(m => m.URLCode == guid);

            appRequest.RefuseDate = DateTime.Now;
            if (db.SaveChanges() > 0)
            {
                var ownerRole = db.CalendarRoles.Include("User").Where(m => m.Calendar.ID == appRequest.Calendar.ID).ToList().OfType<OwnerRole>().FirstOrDefault();
                var owner = ownerRole.User;
                try
                {
                    UserMailer.RefusedAppointmentRequest(new RefusedAppointmentRequestData { Addressee = appRequest.RequestorEmail, CalendarOwnerName = owner.Name, Subject = "Refused appointment request", ViewName = "RefusedAppointmentRequestMail", Appointment = appRequest }).Send();
                }
                catch (Exception e)
                {
                }
                return Json(new
                {
                    success = true
                });
            }

            return Json(new { success = false, message = "something went wrong" });
        }

        public ActionResult Month(int id, int? year, int? month)
        {
            var date = DateTime.Now;
            if (year.HasValue && month.HasValue) date = new DateTime((int)year, (int)month, 1);

            var calendar = db.Calendars.Find(id);

            if (calendar == null)
                return HttpNotFound();

            var user = WebCalendarUser.GetUserProfile(db);
            if (!calendar.IsPublic && user == null)
            {
                return View("~/Views/Calendar/NoAccess.cshtml");
            }

            // be van jelentkezve, és roleon keresztük hozzáférhet a naptárhoz
            if (user != null)
            {
                var role = user.CalendarRoles.FirstOrDefault(m => m.Calendar.ID == id);
                if (role != null)
                {
                    var model = new CalendarIndexDTO { CalendarID = calendar.ID, Year = date.Year, Month = date.Month, DateToShow = date, Calendar = calendar, Role = role };
                    return View(model);
                }
            }



            // Publikus
            if (calendar.IsPublic)
            {
                var model = new CalendarIndexDTO { CalendarID = calendar.ID, Year = date.Year, Month = date.Month, DateToShow = date, Calendar = calendar, Role = null };
                return View(model);
            }

            return HttpNotFound();
        }

    }
}
